home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Washington_1988 / DevCon88.1 / Assembler / intserver / int.asm next >
Encoding:
Assembly Source File  |  1992-08-27  |  8.9 KB  |  217 lines

  1.  
  2. ;
  3. ; Copyright (c) 1988 Commodore-Amiga, Inc.
  4. ;
  5. ; Executables based on this information may be used in software
  6. ; for Commodore Amiga computers.  All other rights reserved.
  7. ;
  8. ; This information is provided "as is"; no warranties are made.
  9. ; All use is at your own risk, and no liability or responsibility is assumed.
  10. ;
  11.  
  12.         SECTION    example,CODE
  13. ;=============================================================================
  14. ; An example to write to the CLI window every second until CTRL/C is pressed.
  15. ;=============================================================================
  16.         NOLIST
  17.         INCLUDE    "exec/types.i"
  18.         INCLUDE    "exec/memory.i"
  19.         INCLUDE    "exec/interrupts.i"
  20.         INCLUDE    "hardware/intbits.i"
  21.         INCLUDE    "libraries/dos.i"
  22.         LIST
  23.  
  24. ; first we define the global data we will be using throughout the program
  25.     STRUCTURE globals,0
  26.         APTR    SysLib        exec library base
  27.         APTR    DosLib        dos library base
  28.         APTR    IntServer    pointer to our interrupt server
  29.         UWORD    Ticks        number of ticks that occured
  30.         ULONG    OutHandle    the output file handle for writing
  31.         APTR    ThisTask    current task address
  32.         ULONG    WaitMask    sigs we will wait for
  33.         ULONG    TickMask    what int handler signals task with
  34.     LABEL globals_SIZEOF
  35.  
  36. ; now we define what external library routines we will be using in this code
  37.         XREF    _AbsExecBase,_LVOOpenLibrary,_LVOCloseLibrary
  38.         XREF    _LVOAllocMem,_LVOFreeMem,_LVOFindTask
  39.         XREF    _LVOAddIntServer,_LVORemIntServer
  40.         XREF    _LVOAllocSignal,_LVOWait,_LVOSignal
  41.         XREF    _LVOOutput,_LVOWrite
  42.  
  43. ;============================================================================
  44. ;Standard initialisation to get the global data space and libraries required
  45. ;============================================================================
  46. Main        moveq.l    #(globals_SIZEOF/2)-1,d0
  47. 10$        clr.w    -(sp)            clear global space
  48.         dbra    d0,10$
  49.         movea.l    sp,a5            a5 always points to globals
  50.         movea.l    _AbsExecBase,a6        get exec.library base
  51.         move.l    a6,SysLib(a5)        and stash it for later
  52.  
  53.         lea.l    DosName(pc),a1        open dos.library
  54.         moveq.l    #33,d0            version 33 or greater
  55.         jsr    _LVOOpenLibrary(a6)
  56.         move.l    d0,DosLib(a5)        save the pointer
  57.         beq    Exit            didn't get it
  58.  
  59. ;============================================================================
  60. ; now get the memory for the interrupt server and initialise the data area
  61. ;============================================================================
  62.         moveq.l    #IS_SIZE,d0        size of server node
  63.         move.l    #MEMF_PUBLIC!MEMF_CLEAR,d1
  64.         jsr    _LVOAllocMem(a6)    get some memory for it
  65.         move.l    d0,IntServer(a5)    save pointer to server
  66.         beq    Exit            didn't get server memory
  67.         movea.l    d0,a1            fill in the structure
  68.         move.b    #NT_INTERRUPT,LN_TYPE(a1)  set the node type
  69.         move.b    #20,LN_PRI(a1)        set priority of the server
  70.         lea.l    IntServerName(pc),a0    set up a name for the node
  71.         move.l    a0,LN_NAME(a1)
  72.         move.l    a5,IS_DATA(a1)        server can see globals
  73.         lea.l    IntServerCode(pc),a0    set up pointer to the code
  74.         move.l    a0,IS_CODE(a1)        in server init complete
  75.         
  76. ;============================================================================
  77. ; do all the DOS initialisation to find the output handle and write a message
  78. ;============================================================================
  79.         movea.l    DosLib(a5),a6        using dos library now
  80.         jsr    _LVOOutput(a6)        get output file handle
  81.         move.l    d0,OutHandle(a5)    and save it
  82.         move.l    d0,d1            writing to stdout
  83.         lea.l    Msg1(pc),a0
  84.         move.l    a0,d2            pointer to msg in d2
  85.         moveq.l    #Msg1End-Msg1,d3    length in d3
  86.         jsr    _LVOWrite(a6)        write out the message
  87.  
  88. ;============================================================================
  89. ; get a signal bit that the interrupt server can signal us with every second
  90. ;============================================================================
  91.         movea.l    SysLib(a5),a6        using exec.library again
  92.         moveq.l    #-1,d0            any signal will do
  93.         jsr    _LVOAllocSignal(a6)
  94.         moveq.l    #0,d1            convert signum to a mask
  95.         bset.l    d0,d1
  96.         move.l    d1,TickMask(a5)        and save it for int server
  97.         ori.l    #SIGBREAKF_CTRL_C,d1    we're waiting for CTRL/C too
  98.         move.l    d1,WaitMask(a5)        stash combined sig bits
  99.  
  100. ;============================================================================
  101. ; generate a pointer to this task so that the interrupt server can find us.
  102. ;============================================================================
  103.         suba.l    a1,a1            find this task
  104.         jsr    _LVOFindTask(a6)
  105.         move.l    d0,ThisTask(a5)        and stash the address
  106.  
  107. ;============================================================================
  108. ; now that everything is initialised, its safe to add the interrupt server
  109. ;============================================================================
  110.         move.w    #60,Ticks(a5)        initialise tick count
  111.         movea.l    IntServer(a5),a1    get the intserver node
  112.         moveq.l    #INTB_VERTB,d0        hooking into VBlank int
  113.         jsr    _LVOAddIntServer(a6)    start it up
  114.  
  115. ;============================================================================
  116. ; The main loop of this program. Waits for a signal from the interrupt server
  117. ; or from the user pressing CTRL/C and does the appropriate things.
  118. ;============================================================================
  119. WaitLoop    move.l    SysLib(a5),a6        using exec for Wait
  120.         move.l    WaitMask(a5),d0        get sigs we are waiting for
  121.         jsr    _LVOWait(a6)        go to sleep
  122.         btst.l    #SIGBREAKB_CTRL_C,d0    did we get a CTRL/C ?
  123.         bne.s    Stopped            yes, exit the program
  124.  
  125. ;============================================================================
  126. ; we were woken up by the interrupt routine so print out the word tick!
  127. ;============================================================================
  128.         movea.l    DosLib(a5),a6        using dos.library again
  129.         move.l    OutHandle(a5),d1    writing to CLI window
  130.         lea.l    Msg2(pc),a0        printing this message
  131.         move.l    a0,d2
  132.         moveq.l    #Msg2End-Msg2,d3    this length
  133.         jsr    _LVOWrite(a6)        write the message out
  134.         bra.s    WaitLoop        and wait for more signals
  135.  
  136. ;============================================================================
  137. ; user pressed CTRL/C so remove interrupt server and print the done message.
  138. ;============================================================================
  139. Stopped        movea.l    SysLib(a5),a6        using exec.library
  140.         movea.l    IntServer(a5),a1    removing this int server
  141.         moveq.l    #INTB_VERTB,d0        from this server chain
  142.         jsr    _LVORemIntServer(a6)    remove it
  143.  
  144.         movea.l    DosLib(a5),a6        now write out the done msg
  145.         move.l    OutHandle(a5),d1    writing to the CLI window
  146.         lea.l    Msg3(pc),a0        printing this message
  147.         move.l    a0,d2
  148.         moveq.l    #Msg3End-Msg3,d3    this length
  149.         jsr    _LVOWrite(a6)        write it out
  150.  
  151. ;============================================================================
  152. ; The main exit point of this program.  It uses the fact that the global
  153. ; memory is zeroed at startup time to determine which resources have been
  154. ; opened or allocated.  Cleanup is done in the same order as initialisation
  155. ; so that as soon as a zero value is found, cleanup is considered complete.
  156. ;============================================================================
  157. Exit        movea.l    SysLib(a5),a6        using exec for cleanups
  158.         tst.l    DosLib(a5)        did we get dos.library ?
  159.         beq.s    ReallyExit        no more cleanup needed
  160.         movea.l    DosLib(a5),a1        close dos library
  161.         jsr    _LVOCloseLibrary(a6)
  162.  
  163.         tst.l    IntServer(a5)        did we get mem for intserver
  164.         beq.s    ReallyExit        no, so no more cleanup
  165.         movea.l    IntServer(a5),a1    free server memory
  166.         moveq.l    #IS_SIZE,d0
  167.         jsr    _LVOFreeMem(a6)
  168.  
  169. ;============================================================================
  170. ; and the final exit point that cleans up our globals off the stack area.
  171. ;============================================================================
  172. ReallyExit    lea.l    globals_SIZEOF(sp),sp    reclaim stack space
  173.         moveq.l    #0,d0            non error return for CLI
  174.         rts                bye-bye
  175.  
  176.  
  177. ;============================================================================
  178. ; This is the actual interrupt server that is called every 60th of a second
  179. ; on the vertical blank interrupt chain.  It is entered with a1 pointing to
  180. ; our global data (because we put a5 into IS_DATA) and a6 pointing to exec.
  181. ;============================================================================
  182. IntServerCode    move.l    a6,-(sp)
  183.         movea.l    _AbsExecBase,a6
  184.         subq.w    #1,Ticks(a1)        decrement the tick count
  185.         bne.s    IntDone            not at 0 yet
  186.  
  187. ; ticks reached 0 so send the appropriate signal to the main task
  188.         move.w    #60,Ticks(a1)        re-initialise tick count
  189.         move.l    TickMask(a1),d0        we want to send this signal
  190.         movea.l    ThisTask(a1),a1        to this task
  191.         jsr    _LVOSignal(a6)        so it wakes up
  192.  
  193. ; we return 0 here so that other handlers get called too.  A non zero return
  194. ; terminates the server chain and no server at a lower pri would get called
  195. IntDone        moveq.l    #0,d0            other handlers get a chance
  196.         move.l    (sp)+,a6
  197.         rts
  198.  
  199.  
  200. ; Text used by the program.  It's OK to put them here because they are static
  201. DosName        DC.B    'dos.library',0
  202.         CNOP    0,2
  203.  
  204. IntServerName    DC.B    'tick server',0
  205.         CNOP    0,2
  206.  
  207. Msg1        DC.B    'Interrupt server example starting',10
  208. Msg1End        CNOP    0,2
  209.  
  210. Msg2        DC.B    'tick!',10
  211. Msg2End        CNOP    0,2
  212.  
  213. Msg3        DC.B    '******* B-O-O-O-O-O-O-O-M *******',10
  214. Msg3End        CNOP    0,2
  215.  
  216.         END
  217.